package com.gjy.design.prototype;

import org.apache.commons.lang3.SerializationUtils;

/**
 * @author gjy
 * @version 1.0
 * @since 2025-11-11 09:45:27
 */
public class Demo {

    public static void main(String[] args) {
        Address address = new Address("aa", 11);
        Person person = new Person("a", 1, address);
        System.out.println(person.hashCode());
        System.out.println(address.hashCode());

        Person clone = SerializationUtils.clone(person);
        System.out.println(clone.hashCode());
        System.out.println(clone.getAddress().hashCode());
    }

    private static void e1() {
        // ---------------- 1) Cloneable 方式 ----------------
        Person p1 = new Person("Bob", 25, new Address("Elm St", 456));
        Person p1Clone = p1.clone();

        // 修改原对象引用字段，验证深拷贝是否成功
        p1.getAddress().setStreet("Changed St");
        System.out.println("p1   = " + p1);                     // street = "Changed St"
        System.out.println("p1Clone = " + p1Clone);             // street = "Elm St"

        // ---------------- 2) 拷贝构造器 ----------------
        Person p2 = new Person("Charlie", 28, new Address("Oak St", 789));
        Person p2Copy = new Person(p2);
        p2.getAddress().setHouseNumber(999);
        System.out.println("p2   = " + p2);                     // houseNumber = 999
        System.out.println("p2Copy = " + p2Copy);               // houseNumber = 789

        // ---------------- 3) 序列化克隆 ----------------
        Person p3 = new Person("Dana", 35, new Address("Pine St", 111));
        Person p3Copy = p3.deepCopyViaSerialization();
        p3.getAddress().setStreet("Birch St");
        System.out.println("p3   = " + p3);                     // street = "Birch St"
        System.out.println("p3Copy = " + p3Copy);               // street = "Pine St"

        // ---------------- 4) Supplier（函数式） ----------------
        java.util.function.Supplier<Person> personSupplier = Person::createPrototype;
        Person p4 = personSupplier.get();   // 首次获取（原型）
        Person p4Clone = personSupplier.get(); // 再次获取（仍是同一个原型实例——这里使用原型时需要自行实现克隆）
        // 为演示真正克隆，使用注册表方式
        Person.PrototypeRegistry registry = new Person.PrototypeRegistry();
        registry.addPrototype("default", Person.createPrototype());
        Person p4FromReg = registry.getPrototype("default");
        p4FromReg.getAddress().setStreet("Maple St");
        System.out.println("p4FromReg = " + p4FromReg);
    }

}
